﻿using System;
using System.Linq.Expressions;
using System.Linq;
using Cesave.Domain.PermisosModule.Contracts.Estados;
using Cesave.Domain.PermisosModule.Entities;
using Cesave.Infrastructure.CrossCutting.Logging;
using Cesave.Infrastructure.Data.PermisosModule.Context;
using Cesave.Infrastructure.Data.PermisosModule.Repositories;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Cesave.Infrastructure.Data.PermisosModule.Tests.RepositoriesTests
{
    [TestClass]
    public class EstadoRepositoryTests
        : GenericRepositoryTestsBase<Estado>
    {
        #region Overrides of GenericRepositoryTestsBase<Estado>

        /// <summary>
        /// Specification of filter expression for a particular type
        /// </summary>
        public override Expression<Func<Estado, bool>> FilterExpression
        {
            get
            {
                return estado => estado.EstadoId == 26;
            }
        }

        /// <summary>
        /// Specification of order by expression for a particular type
        /// </summary>
        public override Expression<Func<Estado, int>> OrderByExpression
        {
            get
            {
                return estado => estado.EstadoId;
            }
        }

        #endregion

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void FindEstadosByStatusSpecification_Null_Specification_ThrowsArgumentNullException()
        {
            // Arrange
            IPermisosModuleContext context = GetContext();
            ITraceManager traceManager = GetTraceManager();
            IEstadoRepository repository = new EstadoRepository(context, traceManager);

            EstadosByStatusSpecification specification = null;

            // Act
            var actual = repository.FindEstadosByStatusSpecification(specification);
        }

        [TestMethod]
        public void FindEstadosByStatusSpecification_Invoke()
        {
            // Arrange
            IPermisosModuleContext context = GetContext();
            ITraceManager traceManager = GetTraceManager();
            IEstadoRepository repository = new EstadoRepository(context, traceManager);

            var specification = new EstadosByStatusSpecification(false);

            // Act
            var actual = repository.FindEstadosByStatusSpecification(specification);

            // Assert
            Assert.IsNotNull(actual);
			actual.ToList().ForEach(estado =>
			{
				Assert.IsFalse(estado.Status);
			});
        }

		[TestMethod]
		[ExpectedException(typeof(InvalidOperationException))]
		public void FindEstadoByGuidSpecification_Empty_Guid_Throws_InvalidOperationException()
		{
			// Arrange
			IPermisosModuleContext context = GetContext();
			ITraceManager traceManager = GetTraceManager();
			IEstadoRepository repository = new EstadoRepository(context, traceManager);

			Guid estadoGuid = Guid.Empty;
			EstadoByGuidSpecification specification = new EstadoByGuidSpecification(estadoGuid);

			// Act
			var estados = repository.FindEstadoByGuidSpecification(specification);
		}

        [TestMethod]
        public void FindEstadoByGuidSpecification_Invoke()
        {
            // Arrange
            IPermisosModuleContext context = GetContext();
            ITraceManager traceManager = GetTraceManager();
            IEstadoRepository repository = new EstadoRepository(context, traceManager);

			Guid estadoGuid = new Guid("B13F5C3F-AA42-4943-A8E9-49BA546EE5D1");
			EstadoByGuidSpecification specification = new EstadoByGuidSpecification(estadoGuid);

            // Act
            var actual = repository.FindEstadoByGuidSpecification(specification);

            // Assert
			Assert.AreEqual(estadoGuid, actual.EstadoGuid);
        }
    }
}
